package com.gopay.common.cps.dao.bank.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Repository;

import com.gopay.common.base.dao.impl.BaseReadDAOImpl;
import com.gopay.common.constants.bank.BankOrderStatus;
import com.gopay.common.constants.bank.BankOrderType;
import com.gopay.common.constants.bank.BisBankBusinessProd;
import com.gopay.common.constants.trans.TxnStaCode;
import com.gopay.common.cps.dao.bank.BankOrderQueryDAO;
import com.gopay.common.domain.bank.BankOrder;

/**
 * 银行流水查询
 * 
 * @BankOrderDAOImpl.java
 * @author yaobo
 * @2013-3-19 上午09:56:20 www.gopay.com.cn Inc.All rights reserved.
 */
@Repository("bankOrderQueryDAO")
public class BankOrderQueryDAOImpl extends BaseReadDAOImpl<BankOrder, String> implements BankOrderQueryDAO {
	@Override
    public List<BankOrder> getCheckBcdlOrder(String bank,String orderStatus, int pageIndex, int pageSize) {
        StringBuffer hql = new StringBuffer("");
        hql.append("from BankOrder ");
        hql.append("where orderStatus = :orderStatus   ");
        hql.append("and bankBizProdCode = :bankBizProdCode ");
        hql.append("and orderType = :orderType and bankCode=:bankCode and  totalCheckTimes <= :totalCheckTimes ");       
        hql.append("order by totalCheckTimes,orderId");

        Map<String, Object> params = new HashMap<String, Object>();
        params.put("orderStatus", orderStatus);
        params.put("bankBizProdCode", BisBankBusinessProd._09.value);
        params.put("orderType", BankOrderType.GOPAY_BIS_ORDER);
        params.put("bankCode", bank);
        params.put("totalCheckTimes", 7);
        List<BankOrder> list = this.findByHql(hql.toString(), params, pageIndex, pageSize);

        return list;
    }
	@Override
	public int getCheckOrderCount(String orderStatus,String bank) {
		 StringBuffer hql = new StringBuffer("");
	        hql.append("select count(*) from BankOrder ");
	        hql.append("where orderStatus = :orderStatus and totalCheckTimes <= :totalCheckTimes ");
	        hql.append("and bankBizProdCode = :bankBizProdCode and bankCode=:bankCode ");
	        hql.append("and orderType = :orderType ");      

	        Map<String, Object> params = new HashMap<String, Object>();
	        params.put("orderStatus", orderStatus);
	        params.put("totalCheckTimes", 7);
	        params.put("bankBizProdCode", BisBankBusinessProd._09.value);
	        params.put("orderType", BankOrderType.GOPAY_BIS_ORDER);
	        params.put("bankCode", bank);
	        
	        int rsCount = this.findCountByHql(hql.toString(), params);

	        return rsCount;
	}
    @Override
    public List<BankOrder> getCheckOrder(String orderStatus, int count, int pageIndex, int pageSize) {
    	if(BankOrderStatus.BANK_CALL_SUCCESS.equals(orderStatus)){
    		return getBankCallSuCheckOrder( count,  pageIndex,  pageSize);
    	}
        StringBuffer hql = new StringBuffer("");
        hql.append("from BankOrder ");
        hql.append("where orderStatus = :orderStatus and totalCheckTimes = :totalCheckTimes ");
        hql.append(" and bankBizProdCode != :bankBizProdCode ");
        hql.append(" and orderType = :orderType ");       
        
        if (!StringUtils.equals("96", orderStatus)) {
        	hql.append(" and bankCode!='ICBC' and   bankCode!='BOC' and bankCode!='CCB'");
        }
        hql.append("order by orderId");
        
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("orderStatus", orderStatus);
        params.put("totalCheckTimes", count);
        params.put("bankBizProdCode", BisBankBusinessProd._09.value);
      
        params.put("orderType", BankOrderType.GOPAY_BIS_ORDER);
       
        
        List<BankOrder> list = this.findByHql(hql.toString(), params, pageIndex, pageSize);

        return list;
    }
    @Override
    public List<BankOrder> getCheckOrderByBank(String orderStatus, int pageIndex, int pageSize,String bankCode) {
        StringBuffer hql = new StringBuffer("");
        hql.append("from BankOrder ");
        hql.append("where orderStatus = :orderStatus   ");
        hql.append(" and bankBizProdCode != :bankBizProdCode and bankCode=:bankCode and totalCheckTimes<7");
        hql.append(" and orderType = :orderType ");       
        hql.append("order by totalCheckTimes,orderId");

        Map<String, Object> params = new HashMap<String, Object>();
        params.put("orderStatus", orderStatus);
        params.put("bankBizProdCode", BisBankBusinessProd._09.value);
        params.put("orderType", BankOrderType.GOPAY_BIS_ORDER);
        params.put("bankCode", bankCode);
        List<BankOrder> list = this.findByHql(hql.toString(), params, pageIndex, pageSize);

        return list;
    }
    private List<BankOrder> getBankCallSuCheckOrder(int count, int pageIndex,
			int pageSize) {
    	StringBuffer hql = new StringBuffer("");
   	 	Map<String, Object> params = new HashMap<String, Object>();
        hql.append("select bis from BankOrder bis,CpsGenMainOrder cps ");
        hql.append(" where bis.orderId = cps.gopayOrderId and bis.orderStatus = :orderStatus ");
        hql.append(" and bis.bankBizProdCode != :bankBizProdCode and cps.txnStaCd!=:txnStaCd");
        hql.append(" order by bis.orderId");
        
        params.put("orderStatus", BankOrderStatus.BANK_CALL_SUCCESS.toString());
        params.put("bankBizProdCode", BisBankBusinessProd._09.value);
        params.put("txnStaCd", TxnStaCode.TXN_STA_CD_20000.value);
        
        List<BankOrder> list = findByHql(hql.toString(), params, pageIndex, pageSize);
        return list;
	}

	@Override
    public List<BankOrder> getCheckBcdlOrder(String orderStatus, int count, int pageIndex, int pageSize) {
        StringBuffer hql = new StringBuffer("");
        hql.append("from BankOrder ");
        hql.append("where orderStatus = :orderStatus and totalCheckTimes <= :totalCheckTimes ");
        hql.append("and bankBizProdCode = :bankBizProdCode ");
        hql.append("and orderType = :orderType ");       
        hql.append("order by orderId");

        Map<String, Object> params = new HashMap<String, Object>();
        params.put("orderStatus", orderStatus);
        params.put("totalCheckTimes", count);
        params.put("bankBizProdCode", BisBankBusinessProd._09.value);
        params.put("orderType", BankOrderType.GOPAY_BIS_ORDER);

        List<BankOrder> list = this.findByHql(hql.toString(), params, pageIndex, pageSize);

        return list;
    }

    @Override
    public int getCheckOrderCount(String orderStatus, int count) {
    	if(BankOrderStatus.BANK_CALL_SUCCESS.equals(orderStatus)){
    		return getBankCallSuCheckOrderCount(count);
    	}
        StringBuffer hql = new StringBuffer("");
        hql.append("select count(*) from BankOrder ");
        hql.append("where orderStatus = :orderStatus and totalCheckTimes = :totalCheckTimes ");
        if (!StringUtils.equals("96", orderStatus)) {
            hql.append(" and bankBizProdCode != :bankBizProdCode ");
            hql.append(" and bankCode!='ICBC' and   bankCode!='BOC' and bankCode!='CCB'");
        }
        hql.append("and orderType = :orderType ");       
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("orderStatus", orderStatus);
        params.put("totalCheckTimes", count);
        if (!StringUtils.equals("96", orderStatus)) {
            params.put("bankBizProdCode", BisBankBusinessProd._09.value);
        }
        	
        params.put("orderType", BankOrderType.GOPAY_BIS_ORDER);
       
        int rsCount = this.findCountByHql(hql.toString(), params);

        return rsCount;
    }

    private int getBankCallSuCheckOrderCount(int count) {
    	StringBuffer hql = new StringBuffer("");
        hql.append("select count(bis.orderId) from BankOrder bis,CpsGenMainOrder cps ");
        hql.append("where bis.orderId = cps.gopayOrderId and bis.orderStatus = :orderStatus  ");
        hql.append(" and cps.txnStaCd!=:txnStaCd ");
        hql.append(" and bis.bankBizProdCode != :bankBizProdCode ");

        Map<String, Object> params = new HashMap<String, Object>();
        params.put("orderStatus", BankOrderStatus.BANK_CALL_SUCCESS.toString());
        params.put("bankBizProdCode", BisBankBusinessProd._09.value);
        params.put("txnStaCd", TxnStaCode.TXN_STA_CD_20000.value);
        
        int rsCount = this.findCountByHql(hql.toString(), params);

        return rsCount;
	}

	@Override
    public int getCheckBcdlOrderCount(String orderStatus, int count) {
        StringBuffer hql = new StringBuffer("");
        hql.append("select count(*) from BankOrder ");
        hql.append("where orderStatus = :orderStatus and totalCheckTimes <= :totalCheckTimes ");
        hql.append("and bankBizProdCode = :bankBizProdCode ");
        hql.append("and orderType = :orderType ");      

        Map<String, Object> params = new HashMap<String, Object>();
        params.put("orderStatus", orderStatus);
        params.put("totalCheckTimes", count);
        params.put("bankBizProdCode", BisBankBusinessProd._09.value);
        params.put("orderType", BankOrderType.GOPAY_BIS_ORDER);

        int rsCount = this.findCountByHql(hql.toString(), params);

        return rsCount;
    }

    @Override
    public BankOrder getCheckOrderByOutOrderId(final String gopayOutOrderId) {

        String hql = "from BankOrder where outOrderId = :outOrderId";

        Map<String, Object> params = new HashMap<String, Object>();
        params.put("outOrderId", gopayOutOrderId);

        List<BankOrder> list = this.findByHql(hql.toString(), params);
        if (null == list || list.isEmpty()) {
            return null;
        }

        return list.get(0);
    }
    
    @Override
	public BankOrder getCheckOrderByGopayOrderId(String gopayOrderId) {

        String hql = "from BankOrder where orderId = :gopayOrderId";

        Map<String, Object> params = new HashMap<String, Object>();
        params.put("gopayOrderId", gopayOrderId);

        List<BankOrder> list = this.findByHql(hql.toString(), params);
        if (null == list || list.isEmpty()) {
            return null;
        }

        return list.get(0);
	}
    @Override
    public BankOrder getEnable(String gopayOrderId) {
        String hql = "from BankOrder where orderId = :gopayOrderId";

        Map<String, Object> params = new HashMap<String, Object>();
        params.put("gopayOrderId", gopayOrderId);

        List<BankOrder> list = this.findByHql(hql.toString(), params);
        if (null == list || list.isEmpty()) {
            return null;
        }

        if (list.size() == 1) {
            return list.get(0);
        }

        BankOrder bankOrder = null;
        for (Iterator<BankOrder> it = list.iterator(); it.hasNext();) {
            bankOrder = it.next();

            if (StringUtils.equals("02", bankOrder.getOrderStatus())
                    || StringUtils.equals("03", bankOrder.getOrderStatus())
                    || StringUtils.equals("04", bankOrder.getOrderStatus())) {
                return bankOrder;
            }
        }

        return list.get(0);
    }
	@Override
	public int getCheckOrderCountByBank(String orderStatus,String bankCode) {
		StringBuffer hql = new StringBuffer("");
        hql.append("select count(*) from BankOrder ");
        hql.append("where orderStatus = :orderStatus  and bankCode=:bankCode  and totalCheckTimes <7");
        if (!StringUtils.equals("96", orderStatus)) {
            hql.append(" and bankBizProdCode != :bankBizProdCode ");
        }
        hql.append("and orderType = :orderType ");       
        
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("bankCode", bankCode);
        params.put("orderStatus", orderStatus);
        if (!StringUtils.equals("96", orderStatus)) {
            params.put("bankBizProdCode", BisBankBusinessProd._09.value);
        }
        params.put("orderType", BankOrderType.GOPAY_BIS_ORDER);

        int rsCount = this.findCountByHql(hql.toString(), params);

        return rsCount;
	}
	
}